package com.basaji.security;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.providers.AbstractAuthenticationToken;

import com.basaji.domain.pojo.Account;

/**
 * An {@link org.acegisecurity.Authentication} implementation that holds three
 * fields of a simple login request, which consists of principal, type of
 * principal and password. <br />
 * Principal here is an object that can identify a user. And credentials here is
 * an object that can verify that the login request is sent by the user himself.
 * These two objects are required to be set of type {@link Object} and usually
 * would be set by {@link String}.
 */
public class PrincipalPasswordAuthenticationToken extends AbstractAuthenticationToken {

    private static final long serialVersionUID = 2649807609384747058L;

    /**
     * object that represent the login user.
     */
    private Object principal;

    /**
     * The credentials that prove the principal is correct. This is usually a
     * password, but could be anything relevant to the
     * <code>AuthenticationManager</code>. Callers are expected to populate
     * the credentials.
     */
    private Object credentials;

    /**
     * represent the current login user.
     */
    private Account currentAccount;

    /**
     * 
     * constructs a login request with {@link #principalType} set to
     * {@code null} and {@link #isAuthenticated()} return false.
     * 
     * @param principal
     *            identifier of a user
     * @param credentials
     *            usually would be a password.
     */
    public PrincipalPasswordAuthenticationToken(Object principal, Object credentials) {
        this(null, principal, credentials, null, false);
    }

    /**
     * construct the authentication object after proving the login request is
     * valid and is sent by the user himself.
     * 
     * @param authorities
     *            authorities of the login user.
     * @param principalType
     *            the type of principal.
     * @param principal
     *            identifier of a user.
     * @param credentials
     *            usually would be a password.
     * @param currentLogin
     *            login object of the current login user.
     * @param authenticated
     */
    public PrincipalPasswordAuthenticationToken(GrantedAuthority[] authorities, Object principal, Object credentials,
            Account currentLogin, boolean authenticated) {
        super(authorities);
        this.principal = principal;
        this.credentials = credentials;
        this.currentAccount = currentLogin;
        super.setAuthenticated(authenticated);
    }

    /**
     * {@inheritDoc}
     */
    public Object getCredentials() {
        return credentials;
    }

    /**
     * {@inheritDoc}
     */
    public Object getPrincipal() {
        return principal;
    }

    /**
     * get the login object of the current login user.
     * 
     * @return the login object of the current login user.
     */
    public Account getCurrentAccount() {
        return currentAccount;
    }

    /**
     * Override this method so that any one else cannot set this authentication
     * to be authenticated (and become more secure). In order to set
     * authenticated to true, use
     * {@link #PrincipalPasswordAuthenticationToken(GrantedAuthority[], String, Object, Object, Account, boolean)}
     * instead.
     * 
     * @param authenticated
     *            If this authentication token has been authenticated.
     */
    @Override
    public void setAuthenticated(boolean authenticated) {
        if (authenticated) {
            throw new UnsupportedOperationException("setAuthenticated");
        }
        super.setAuthenticated(false);
    }
    
    public void setCurrentAccount(Account account){
    	currentAccount = account;
    }

}
